package com.panda.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.panda.common.core.domain.AjaxResult;
import com.panda.common.utils.DateUtils;
import com.panda.system.common.constant.EnumConstants;
import com.panda.system.domain.PandaWorkbench;
import com.panda.system.domain.TPandaTaskUser;
import com.panda.system.dto.TaskAdjust;
import com.panda.system.mapper.TPandaTaskUserMapper;
import com.panda.system.service.IPandaWorkbenchService;
import com.panda.system.service.ITPandaTaskUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * 操作任务Service业务层处理
 * 
 * @author panda
 * @date 2021-03-04
 */
@Service
@Transactional
public class TPandaTaskUserServiceImpl implements ITPandaTaskUserService 
{
    @Autowired
    private TPandaTaskUserMapper tPandaTaskUserMapper;

    @Autowired
    private IPandaWorkbenchService workbenchService;

    /**
     * 查询操作任务
     * 
     * @param id 操作任务ID
     * @return 操作任务
     */
    @Override
    public TPandaTaskUser selectTPandaTaskUserById(Long id)
    {
        return tPandaTaskUserMapper.selectTPandaTaskUserById(id);
    }

    /**
     * 查询操作任务列表
     * 
     * @param tPandaTaskUser 操作任务
     * @return 操作任务
     */
    @Override
    public List<TPandaTaskUser> selectTPandaTaskUserList(TPandaTaskUser tPandaTaskUser)
    {
        return tPandaTaskUserMapper.selectTPandaTaskUserList(tPandaTaskUser);
    }

    /**
     * 新增操作任务
     * 
     * @param tPandaTaskUser 操作任务
     * @return 结果
     */
    @Override
    public int insertTPandaTaskUser(TPandaTaskUser tPandaTaskUser)
    {
        tPandaTaskUser.setCreateTime(DateUtils.getNowDate());
        return tPandaTaskUserMapper.insertTPandaTaskUser(tPandaTaskUser);
    }

    /**
     * 修改操作任务
     * 
     * @param tPandaTaskUser 操作任务
     * @return 结果
     */
    @Override
    public int updateTPandaTaskUser(TPandaTaskUser tPandaTaskUser)
    {
        tPandaTaskUser.setUpdateTime(DateUtils.getNowDate());
        return tPandaTaskUserMapper.updateTPandaTaskUser(tPandaTaskUser);
    }

    /**
     * 批量删除操作任务
     * 
     * @param ids 需要删除的操作任务ID
     * @return 结果
     */
    @Override
    public int deleteTPandaTaskUserByIds(Long[] ids)
    {
        return tPandaTaskUserMapper.deleteTPandaTaskUserByIds(ids);
    }

    /**
     * 删除操作任务信息
     * 
     * @param id 操作任务ID
     * @return 结果
     */
    @Override
    public int deleteTPandaTaskUserById(Long id)
    {
        return tPandaTaskUserMapper.deleteTPandaTaskUserById(id);
    }

    @Override
    public void closeTask(String linkId) {
        tPandaTaskUserMapper.closeTask(linkId);
    }

    @Override
    public AjaxResult taskAdjust(TaskAdjust taskAdjust) {
        if(CollectionUtils.isEmpty(taskAdjust.getTaskIds())){
            return AjaxResult.error("请选择需要调整的任务！");
        }
        if(CollectionUtils.isEmpty(taskAdjust.getUserIds())){
            return AjaxResult.error("请选择调整到的用户！");
        }
        List<TPandaTaskUser> tPandaTaskUsers = tPandaTaskUserMapper.selectTPandaTaskUserListByIds(taskAdjust.getTaskIds());

        // 删除通知信息
        for(TPandaTaskUser task:tPandaTaskUsers){
            if(EnumConstants.UserTaskStatus.TO_SEND.getCode().equals(task.getStatus())){
                return AjaxResult.error("任务："+task.getId()+",已转派！");
            }
            PandaWorkbench workbench = new PandaWorkbench();
            workbench.setLinkId(Long.valueOf(task.getLinkId()));
            workbench.setUserId(task.getResponsibleUserId());
            workbench.setExts5(String.valueOf(task.getId()));
            List<PandaWorkbench> pandaWorkbenches = workbenchService.selectPandaWorkbenchList(workbench);
            List<Long> ids = pandaWorkbenches.stream().map(PandaWorkbench::getId).collect(Collectors.toList());
            if(CollectionUtils.isEmpty(ids)){
                continue;
            }
            workbenchService.deletePandaWorkbenchByIds(ids.toArray(new Long[0]));
        }
        
        AtomicReference<Integer> dailyTradingTodo = new AtomicReference<>(0);
        AtomicReference<Integer> reservedTradingTodo = new AtomicReference<>(0);
        tPandaTaskUsers.forEach(item-> {
            dailyTradingTodo.updateAndGet(v -> v + item.getDailyTradingVolume());
            reservedTradingTodo.updateAndGet(v -> v + item.getReservedTradingVolume());
        });
        // 均值
        Integer dailyAverage = dailyTradingTodo.get()/taskAdjust.getUserIds().size();
        Integer reservedAverage = reservedTradingTodo.get()/taskAdjust.getUserIds().size();
        if(dailyTradingTodo.get()>0&&dailyAverage==0){
            dailyAverage =1;
        }
        if(reservedTradingTodo.get()>0&&reservedAverage==0){
            reservedAverage =1;
        }
        if(reservedTradingTodo.get()==0&&dailyTradingTodo.get()==0){
            return AjaxResult.error("待分配的工作量为0！");
        }
        int i=0;
        List<TPandaTaskUser> dayTasksAll = new ArrayList<>(tPandaTaskUsers);
        List<TPandaTaskUser> reservedTasksAll = new ArrayList<>(tPandaTaskUsers);
        for(Long userId:taskAdjust.getUserIds()) {
            i++;
            int dailyTodo = dailyAverage;
            int reserveddo = reservedAverage;
            List<TPandaTaskUser> tasks = new ArrayList<>();
            List<TPandaTaskUser> reserveTasks = new ArrayList<>();
            List<TPandaTaskUser> dayTasks = new ArrayList<>(dayTasksAll);
            for (TPandaTaskUser day : dayTasks) {
                if (dailyTodo <= 0) {
                    break;
                }
                if (day.getDailyTradingVolume() <= 0) {
                    continue;
                }
                TPandaTaskUser task = new TPandaTaskUser();
                task = JSON.parseObject(JSON.toJSONBytes(day), TPandaTaskUser.class);

                task.setReservedTradingVolume(0);
                if (task.getDailyTradingVolume() > dailyTodo) {
                    task.setFpValue(dailyTodo);
                    tasks.add(task);
                    int finalDailyTodo = dailyTodo;
                    dayTasksAll.forEach(item -> {
                        if (item.getId().equals(day.getId())) {
                            item.setDailyTradingVolume(day.getDailyTradingVolume() - finalDailyTodo);
                        }
                    });
                    dailyTodo = 0;
                } else if (task.getDailyTradingVolume() == dailyTodo) {
                    dailyTodo = 0;
                    task.setFpValue(task.getDailyTradingVolume());
                    tasks.add(task);
                    dayTasksAll.removeIf(item -> item.getId().equals(day.getId()));
                } else {
                    dailyTodo = dailyTodo - task.getDailyTradingVolume();
                    task.setFpValue(task.getDailyTradingVolume());
                    tasks.add(task);
                    dayTasksAll.removeIf(item -> item.getId().equals(day.getId()));
                }
            }
            List<TPandaTaskUser> reservedTasks = new ArrayList<>(reservedTasksAll);
            for (TPandaTaskUser day : reservedTasks) {
                if (reserveddo <= 0) {
                    break;
                }
                if (day.getReservedTradingVolume() <= 0) {
                    continue;
                }
                TPandaTaskUser task = new TPandaTaskUser();
                task = JSON.parseObject(JSON.toJSONBytes(day), TPandaTaskUser.class);

                task.setDailyTradingVolume(0);
                if (task.getReservedTradingVolume() > reserveddo) {
                    task.setFpValue(reserveddo);
                    reserveTasks.add(task);
                    int finalReserveddo = reserveddo;
                    reservedTasksAll.forEach(item -> {
                        if (item.getId().equals(day.getId())) {
                            item.setReservedTradingVolume(day.getReservedTradingVolume() - finalReserveddo);
                        }
                    });
                    reserveddo = 0;
                } else if (task.getReservedTradingVolume() == reserveddo) {
                    reserveddo = 0;
                    task.setFpValue(task.getReservedTradingVolume());
                    reserveTasks.add(task);
                    reservedTasksAll.removeIf(item -> item.getId().equals(day.getId()));
                } else {
                    reserveddo = reserveddo - task.getReservedTradingVolume();
                    task.setFpValue(task.getReservedTradingVolume());
                    reserveTasks.add(task);
                    reservedTasksAll.removeIf(item -> item.getId().equals(day.getId()));
                }
            }
            List<Long> dayTaskIds = tasks.stream().map(TPandaTaskUser::getId).collect(Collectors.toList());
            List<Long> reserveTasksIds = reserveTasks.stream().map(TPandaTaskUser::getId).collect(Collectors.toList());
            // 剩余未分配的处理
            if (i == taskAdjust.getUserIds().size()) {
                dayTasksAll.forEach(item -> {
                    if (dayTaskIds.contains(item.getId())) {
                        tasks.forEach(task -> {
                            if (item.getId().equals(task.getId())) {
                                task.setFpValue(task.getFpValue() + item.getDailyTradingVolume());
                            }
                        });
                    } else {
                        item.setReservedTradingVolume(0);
                        item.setFpValue(item.getDailyTradingVolume());
                        tasks.add(item);
                    }

                });
                reservedTasksAll.forEach(item -> {
                    if (reserveTasksIds.contains(item.getId())) {
                        reserveTasks.forEach(task -> {
                            if (item.getId().equals(task.getId())) {
                                task.setFpValue(task.getFpValue() + item.getReservedTradingVolume());
                            }
                        });
                    } else {
                        item.setDailyTradingVolume(0);
                        item.setFpValue(item.getReservedTradingVolume());
                        reserveTasks.add(item);
                    }
                });
            }
            // 汇总当天单预留单任务
            Map<String, TPandaTaskUser> taskMap = new HashMap<>();
            for (TPandaTaskUser res : reserveTasks) {
                taskMap.put(Long.toString(res.getId()), res);
            }
            Set<String> reserveTaskId = taskMap.keySet();
            List<String> reserveTaskIds = new ArrayList<>(reserveTaskId);
            reserveTaskIds.removeIf(item -> dayTaskIds.contains(Long.valueOf(item)));
            List<TPandaTaskUser> countTasks = new ArrayList<>();
            tasks.forEach(dayTask -> {
                dayTask.setDailyTradingVolume(dayTask.getFpValue());
                TPandaTaskUser reserveTask = taskMap.get(Long.toString(dayTask.getId()));
                if (reserveTask != null) {
                    dayTask.setReservedTradingVolume(reserveTask.getFpValue());
                }
                countTasks.add(dayTask);
            });
            reserveTasks.forEach(item -> {
                if (reserveTaskIds.contains(Long.toString(item.getId()))) {
                    item.setReservedTradingVolume(item.getFpValue());
                    countTasks.add(item);
                }
            });
            // 每人分配到的
            distributionTaskToUser(userId, countTasks);

        }
        
        return AjaxResult.success("任務调整，完成！");
    }

    @Override
    public TPandaTaskUser selectTPandaTaskUserByTask(Long taskId, Long userId) {
        return tPandaTaskUserMapper.selectTPandaTaskUserByTask(taskId,userId);
    }

    @Override
    public List<TPandaTaskUser> getUserTaskListByParentTaskIds(List<Long> taskIds) {
        return tPandaTaskUserMapper.getUserTaskListByParentTaskIds(taskIds);
    }

    private void distributionTaskToUser(Long userId,List<TPandaTaskUser> countTasks){
        for(TPandaTaskUser tPandaTaskUser:countTasks){
            // 查询当前用户对该任务是否有负责
            TPandaTaskUser taskUserSuch = new TPandaTaskUser();
            taskUserSuch.setLinkId(tPandaTaskUser.getLinkId());
            taskUserSuch.setTastDate(tPandaTaskUser.getTastDate());

            taskUserSuch.setResponsibleUserId(userId);
            List<TPandaTaskUser> oldTasks = tPandaTaskUserMapper.selectTPandaTaskUserList(taskUserSuch);
            // 非已转派 且任务开启状态
            if(!CollectionUtils.isEmpty(oldTasks)&&EnumConstants.UserTaskStatus.OPEN.getCode().equals(oldTasks.get(0).getStatus())){
                // 只会有一条
                TPandaTaskUser userTask = oldTasks.get(0);
                userTask.setDailyTradingVolume(userTask.getDailyTradingVolume()+tPandaTaskUser.getDailyTradingVolume());
                userTask.setReservedTradingVolume(userTask.getReservedTradingVolume()+tPandaTaskUser.getReservedTradingVolume());
                // 更新
                tPandaTaskUserMapper.updateTPandaTaskUser(userTask);
            }else {
                // 新建
                TPandaTaskUser addTask = new TPandaTaskUser();
                addTask.setLinkId(String.valueOf(tPandaTaskUser.getLinkId()));
                addTask.setType(EnumConstants.TodoType.TASK_OPERATION.getCode());
                addTask.setResponsibleUserId(userId);
                addTask.setStatus(EnumConstants.SysStatus.OPEN.getCode());
                addTask.setName(tPandaTaskUser.getName());
                addTask.setDailyTradingVolume(tPandaTaskUser.getDailyTradingVolume());
                addTask.setReservedTradingVolume(tPandaTaskUser.getReservedTradingVolume());
                tPandaTaskUserMapper.insertTPandaTaskUser(addTask);
            }
            TPandaTaskUser updateTask = new TPandaTaskUser();
            updateTask.setId(tPandaTaskUser.getId());
            updateTask.setStatus(EnumConstants.UserTaskStatus.TO_SEND.getCode());
            tPandaTaskUserMapper.updateTPandaTaskUser(updateTask);
        }
        
    }
}
